/**
 * 工具条组件
 * @param {*} opt 
 * @returns 
 */
function scToolbar(opt){
    var com = scCommon.instance();
    var crEle = com.crEle;
    
    opt = opt ? opt : {};

    var menus = opt.menus;
    var toolbar = null;
    var layoutRect = null;

    /**
     * 监听器
     */
    var listener = {};
    var dialog = new scDialog();

    /**
     * 创建布局视图
     * @param {*} option 
     */
    this.createView = function(option){
        option = option ? option : {};

        toolbar = crEle();
        toolbar.classList.add("sc-toolbar");

        var tab = createTab(menus);
        toolbar.appendChild(tab);

        addGlobalListener();

        return toolbar;
    }

    /**
     * 所有工具条按钮
     */
    var tabButtons = null;
    var prevMenu = null;
    var lastMenu = null;

    /**
     * 创建选项卡
     * @param {*} menus 
     */
    var createTab = function(menus){
        var tab = crEle();
        var tabHead = crEle();
        var tabBody = crEle();

        tab.classList.add("sc-tab");
        tabHead.classList.add("sc-tab-head");
        tabBody.classList.add("sc-tab-body");

        tabButtons = [];

        for(var i = 0; i < menus.length; i++){
            let menu = menus[i];
            let tabHeadItem = crEle();

            tabHeadItem.classList.add("sc-tab-head-item");

            let label = crEle("span");
            label.innerText = menu.label;

            tabHeadItem.appendChild(label);
            tabHead.appendChild(tabHeadItem);

            let tabBodyItem = crEle();
            tabBodyItem.classList.add("sc-tab-body-item");

            createGroup(tabBodyItem, menu.groups);
            tabBody.appendChild(tabBodyItem);    

            menu.headNode = tabHeadItem;
            menu.bodyNode = tabBodyItem;

            if(menu.selected){
                tabHeadItem.classList.add("selected");
                tabBodyItem.classList.add("selected");
                lastMenu = menu;
            }

            if(menu.selector){
                tabHeadItem.style.display = "none";
            }
        }

        if(!lastMenu){
            menus[0].headNode.classList.add("selected");
            menus[0].bodyNode.classList.add("selected");
            lastMenu = menus[0];
        }

        tabHead.addEventListener("mousedown", (e)=>{
            let isHeadItem = e.target.classList.contains("sc-tab-head-item");
            let isParent = e.target.parentNode.classList.contains("sc-tab-head-item");

            if(isHeadItem || isParent){
                let element = isParent ? e.target.parentNode : e.target;

                let headItem = tabHead.querySelector(".sc-tab-head-item.selected");
                headItem.classList.remove("selected");

                let bodyItem = tabBody.querySelector(".sc-tab-body-item.selected");
                bodyItem.classList.remove("selected");

                element.classList.add("selected");

                for(var i in menus){
                    if(menus[i].headNode === element){
                        menus[i].bodyNode.classList.add("selected");
                        if(lastMenu && lastMenu !== menus[i]){
                            prevMenu = lastMenu;
                        }
                        lastMenu = menus[i];
                        break;
                    }
                }

                e.stopPropagation();
            }
        });

        tabBody.addEventListener("click", (e)=>{
            let isButton = e.target.classList.contains("sc-toolbar-button");
            let isGroup = e.target.parentNode.classList.contains("sc-toolbar-button");
            let isCheckOrRadio = e.target.type == "checkbox" || e.target.type == "radio";
            let element = null;

            if(isButton || isGroup){
                element = isButton ? e.target : e.target.parentNode;
                if(element.querySelector("input[type='checkbox'],input[type='radio']")){
                    return;
                }
            }else if(isCheckOrRadio){
                element = e.target.parentNode.parentNode;
            }

            if(element){
                for(var i = 0; i < tabButtons.length; i++){
                    if(tabButtons[i].element === element){
                        triggerListener("click", tabButtons[i]);
                        break;
                    }
                }
            }

            e.stopPropagation();
        });
        
        tab.appendChild(tabHead);
        tab.appendChild(tabBody);

        return tab;
    }

    /**
     * 创建分组
     * @param {*} bodyItem
     * @param {*} groups 
     */
    var createGroup = function(bodyItem, groups){
        if(!groups) return;

        for(var i = 0; i < groups.length; i++){
            let group = groups[i];

            let groupElement = crEle();
            groupElement.classList.add("sc-toolbar-group");

            let groupElementBody = crEle();
            groupElementBody.classList.add("sc-toolbar-group-body");

            let groupElementFoot = crEle();
            groupElementFoot.classList.add("sc-toolbar-group-foot");
            groupElementFoot.innerText = group.label;
    
            createToolbar(groupElementBody, group);

            groupElement.appendChild(groupElementBody);
            groupElement.appendChild(groupElementFoot);
            bodyItem.appendChild(groupElement);
        }
    }

    /**
     * 模拟行为按钮
     */
    var mockButtons = {};

    /**
     * 创建工具条按钮
     * @param {*} groupBody 分组显示元素
     * @param {*} group 分组数据
     */
    var createToolbar = function(groupBody, group){
        var buttons = group.children;

        if(group.align == "left"){
            groupBody.style.justifyContent = "flex-start";
        }else if(group.align == "center"){
            groupBody.style.justifyContent = "center";
        }else if(group.align == "right"){
            groupBody.style.justifyContent = "flex-end";
        }

        for(var i = 0; i < buttons.length; i++){
            let button = {...buttons[i]};
            let buttonElement = crEle();

            if(button.style){
                for(let j in button.style){
                    buttonElement.style[j] = button.style[j];
                }
            }

            try{
                if(button.component && button.component.name){
                    button.component = instantiateComponent(
                        button.component.name, 
                        button.component.param
                    );
                }
            }catch(e){
                console.error("component " + button.component.name + " is not found");
            }
            
            buttonElement.classList.add("sc-toolbar-button");

            //模拟类型
            if(button.mocktype){
                let name = button.name ? button.name : button.key;

                if(!mockButtons[name]){
                    mockButtons[name] = [];
                }

                mockButtons[name].push(button);
            }

            //色带
            if(button.ribbon){
                let ribbon = crEle(null, "sc-button-ribbon");
                buttonElement.appendChild(ribbon);

                button.effectElement = ribbon;
            }

            let title = button.label;
            if(button.shortcutKey){
                title += "(" + button.shortcutKey + ")";
            }
            buttonElement.setAttribute("title", title);

            //选择框
            if(button.present == "select"){
                let select = crEle("select");
                select.style.width = button.width ? button.width : 50;
                select.style.height = 20;

                button.effectElement = select;

                if(button.list){
                    button.elementList = [];
                    for(var j = 0; j < button.list.length; j++){
                        let option = crEle("option");
                        option.innerText = button.list[j];

                        button.elementList.push({
                            element: option,
                            value: button.list[j]
                        });

                        if(button.bindStyle){
                            option.style[button.bindStyle.key] = button.bindStyle.value.replace("{item}", button.list[j]);
                        }

                        select.appendChild(option);
                    }
                }
                
                buttonElement.appendChild(select);
            }
            //复选框
            else if(button.present == "checkbox"){
                let label = crEle("label");
                let input = crEle("input");

                input.style.verticalAlign = "-2px";
                input.setAttribute("type", "checkbox");
                
                label.innerText = button.label;
                label.prepend(input);

                buttonElement.appendChild(label);

                button.effectElement = input;
            }else if(button.present == "block"){
                if(button.component){
                    buttonElement = button.component.createView({listener: listener});
                }
            }else{
                if(button.icon){
                    let img = crEle("img");
                    img.src = button.icon;
                    if(button.iconSize){
                        if(button.iconSize.width){
                            img.style.width = button.iconSize.width + "px";
                        }
                        if(button.iconSize.height){
                            img.style.height = button.iconSize.height + "px";
                        }
                    }
                    buttonElement.appendChild(img);
                }

                if((!button.icon || button.showAll) && button.label){
                    let span = crEle("span", "sc-toolbar-title");
                    span.innerText = button.label;
                    buttonElement.appendChild(span);
                }

                //下拉框
                if(button.present == "dropdown"){
                    let img = crEle("img");
                    img.src = scToolbarResource.arrowDown;

                    if(!button.arrowLocation || button.arrowLocation == "right"){
                        img.classList.add("sc-arrow-right");

                        buttonElement.style.flexDirection = "row";

                    }else if(button.arrowLocation == "bottom"){
                        img.classList.add("sc-arrow-bottom");

                        buttonElement.style.flexDirection = "column";
                        buttonElement.style.alignItems = "center";
                    }

                    buttonElement.appendChild(img);
                }
            }
            
            button.element = buttonElement;
            button.command = button.command ? button.command : group.command;

            tabButtons.push(button);

            groupBody.appendChild(buttonElement);
        }
    }

    /**
     * 根据名称实例化组件
     * @param {*} name 
     * @param {*} param 
     * @returns 
     */
    var instantiateComponent = function(name, param){
        let exp = "new " + name;
    
        if(param){
            if(typeof(param) == "object"){
                exp += "(" + JSON.stringify(param) + ")";
            }else{
                exp += "('" + param + "')";
            }
        }else{
            exp += "()";
        }

        return eval(exp);
    }

    /**
     * 添加监听器
     */
    var addGlobalListener = function(){
        window.removeEventListener("keydown", windowKeydown);
        window.addEventListener("keydown", windowKeydown);
    }

    /**
     * 键盘事件
     * @param {*} e 
     */
    var windowKeydown = function(e){
        if(!e.ctrlKey && !e.shiftKey && !e.altKey) return;

        var shortKey = "";

        if(e.ctrlKey){
            shortKey += "Ctrl";
        }

        if(e.altKey){
            shortKey += (shortKey ? "+" : "") + "Alt";
        }

        if(e.shiftKey){
            shortKey += (shortKey ? "+" : "") + "Shift"; 
        }

        shortKey += "+" + e.key;

        let btnKey = null;
        let btn = null;

        for(var i in tabButtons){
            btn = tabButtons[i];
            if(!btn.shortcutKey) continue;

            btnKey = btn.shortcutKey.toLowerCase();

            if(btnKey.replace(/[\s]/g, "") == shortKey.toLowerCase()){
                triggerListener("click", tabButtons[i]);

                e.stopPropagation();
                e.preventDefault();

                break;
            }
        }
    }
    
    /**
     * 添加监听器
     * @param {*} name 
     * @param {*} callback 
     */
    this.addEventListener = function(name, callback){
        if(!listener[name]){
            listener[name] = [];
        }

        listener[name].push(callback);
    }

    /**
     * 触发监听
     * @param {*} name 
     * @param {*} button 
     */
    var triggerListener = function(name, button){
        if(!listener[name] || button.__lock) return;

        button.__lock = true;

        try{
            for(var i in listener[name]){
                //模拟类型按钮(radio、checkbox行为按钮)
                if(button.mocktype){
                    changeMockButtonState(button);
                    listener[name][i](button.command, composeMockParam(button), button.option);
                }else if(button.present == "dropdown"){
                    showDropdown(button, listener[name][i]);
                }else if(button.present == "dialog"){
                    showDialog(button, listener[name][i]);
                }else if(button.present == "select"){
                    bindSelect(button, listener[name][i]);
                }else if(button.present == "checkbox"){
                    doCheck(button, listener[name][i]);
                }else{
                    changeElementState(button);
                    setLoading(button);
                    listener[name][i](button.command, composeParam(button), button.option);
                }
            }
        }finally{
            if(button.__lock === true){
                delete button.__lock;
            }
        }
    }

    /**
     * 设置加载提示器
     * @param {*} button 
     * @returns 
     */
    var setLoading = function(button){
        if(!button.loading) return;

        button.option = button.option ? button.option : {};

        let loading = eval("new " + button.loading + "()");

        loading.createView({
            boundRect: layoutRect
        });

        button.option.beforeLoad = (text)=>{
            button.__lock = "loading";
            loading.show(text);
        }

        button.option.afterLoad = ()=>{
            loading.close();
            delete button.__lock;
        }
    }

    /**
     * 改变模拟按钮状态
     * @param {*} button 
     * @param {*} key
     * @param {*} value 
     */
    var changeMockButtonState = function(button, key, value){
        let name = button.name ? button.name : button.key;
        let useVal = value !== undefined;

        key = useVal ? key : button.key;
        value = useVal ? value : button.value;

        let isBoolean = typeof(button.value) == "boolean";
        let buttons = mockButtons[name];
        let btn = null;

        if(button.mocktype == "radio"){
            for(var i in buttons){
                btn = buttons[i];

                if(btn.key == key){
                    if(isBoolean){
                        btn.checked = useVal ? value : !btn.checked;
                    }else if(btn.value == value){
                        btn.checked = true;
                    }else{
                        continue;
                    }
                    
                    changeFocusButton(btn.element, btn.checked);
                    break;
                }
            }

            if(btn.checked){
                for(var j in buttons){
                    if(btn === buttons[j]) continue;
                    
                    buttons[j].checked = false;
                    changeFocusButton(buttons[j].element, buttons[j].checked);
                }
            }

        }else if(button.mocktype == "checkbox"){
            if(isBoolean){
                button.checked = useVal ? value : !button.checked;
            }else{
                if(useVal){
                    if(value){
                        value = value.split("|");
                        button.checked = value.indexOf(button.value) > -1;
                    }else{
                        button.checked = false;
                    }
                }else{
                    button.checked = !button.checked;
                }
            }

            changeFocusButton(button.element, button.checked);
        }
    }

    /**
     * 获取模拟按钮参数
     * @param {*} button 
     */
    var composeMockParam = function(button){
        if(button.mocktype == "radio"){
            let param = {};
            param[button.key] = button.checked 
                ? button.value 
                : typeof(button.value) == "boolean"
                    ? !button.value 
                    : null;

            return param;
        }else if(button.mocktype == "checkbox"){
            let param = {};
            let buttons = mockButtons[button.key];

            param[button.key] = "";
            
            for(var i = 0; i < buttons.length; i++){
                if(buttons[i].checked){
                    param[button.key] += buttons[i].value + (i < buttons.length - 1 ? "|" : "");
                }
            }

            return param;
        }
    }

    /**
     * 更改元素状态
     * @param {*} button 
     * @param {*} index
     */
    var changeElementState = function(button, index){
        if(button.list){
            let ind = null;

            if(index === undefined){
                index = button.selectedIndex;
    
                ind = index === undefined ? 0 : index + 1;
                ind = ind >= button.list.length ? 0 : ind;
    
                button.selectedIndex = ind;
            }else{
                button.selectedIndex = index < 0 ? button.list.length - 1 : index;
                ind = button.selectedIndex;
            }
    
            changeFocusButton(button.element, button.list[0] == button.list[ind]);
        }else if(button.key && button.value){
            button.checked = !button.checked;
            changeFocusButton(button.element, button.checked);
        }
    }

    /**
     * 改变焦点按钮
     * @param {*} element 
     * @param {*} focus 
     */
    var changeFocusButton = function(element, focus){
        if(focus){
            element.classList.add("sc-toolbar-button-focus");
        }else{
            element.classList.remove("sc-toolbar-button-focus");
        }
    }

    /**
     * 组合参数
     * @param {*} button 
     * @returns 
     */
    var composeParam = function(button){
        if(button.list){
            let param = {};
            param[button.key] = button.list[button.selectedIndex];
            return param;
        }else if(button.key && button.value){
            let param = {};
            param[button.key] = button.value;
            return param;
        }

        return button.param;
    }

    /**
     * 组合参数
     * @param {*} button 
     * @param {*} param 
     */
    var composeParam2 = function(button, param){
        let p = null;

        if(button.key){
            p = {};

            if(button.prop){
                p[button.prop] = {};
                p[button.prop][button.key] = param;
            }else{
                p[button.key] = param;
            }

            return p;
        }

        return param;
    }

    /**
     * 更改下拉框状态
     * @param {*} button 
     * @param {*} key 
     * @param {*} value 
     */
    var changeDropdownState = function(button, key, value){
        if(button.key != key) return;
        if(button.list){
            button.selectedIndex = -1;
            
            let isNumber = typeof(value) == "number";
            let item = null;
            for(var i = 0; i < button.list.length; i++){
                item = button.list[i];
                if(isNumber){
                    if(parseFloat(item) == value){
                        button.selectedIndex = i;
                    }
                }else if(item == value){
                    button.selectedIndex = i;
                }
            }
        }
    }

    /**
     * 当前显示的下拉框
     */
    var displayDropdown = null;

    /**
     * 创建并显示下拉框
     * @param {*} button 
     * @param {*} listener
     */
    var showDropdown = function(button, listener){
        var element = button.element;
        var dropdown = element.querySelector(".sc-dropdown-box");

        if(!dropdown){
            dropdown = crEle(null, "sc-dropdown-box");

            button.effectElement = dropdown;

            if(button.component){
                let option = {
                    container: dropdown,
                    listener: listener,
                    triggerListener: (param)=>{
                        param = composeParam2(button, param);
                        listener(button.command, param);
                        hideDropdown(dropdown);
                    },
                    showDialog: (param)=>{
                        for(var i in param){
                            button[i] = param[i];
                        }
                        showDialog(button, listener);
                        hideDropdown(dropdown);
                    }
                };
                if(button.ribbon){
                    option.ribbon = element.querySelector(".sc-button-ribbon");
                }
                dropdown.appendChild(button.component.createView(option));
            }else if(button.list){
                let ul = buildDropdownList.call(this, button);
                dropdown.appendChild(ul);
            }

            element.appendChild(dropdown);

            dropdown.addEventListener("click", (e)=>{
                let isButton = e.target.tagName.toLowerCase() == "li";
                let target = isButton 
                    ? e.target 
                    : e.target.parentNode.tagName.toLowerCase() == "li"
                        ? e.target.parentNode
                        : null;

                if(target){
                    if(!button.subButtons) return;

                    let selectedIndex = -1;
                    let btn = button.subButtons.find((item, index)=>{
                        selectedIndex = index;
                        return item.element === target;
                    });

                    if(btn.present == "dialog"){
                        if(btn.component){
                            showDialog(btn, listener);
                        }
                    }else{
                        let param = composeParam2(button, btn.value);
                        listener(button.command, param);
    
                        button.selectedIndex = selectedIndex;
                    }

                    setMenuListCheck(target, dropdown);
                    hideDropdown(dropdown);

                    e.stopPropagation();
                }
            })
        }
        
        var visible = setDropdownVisible(dropdown, null, element.clientHeight);
        if(visible){
            //属性更改，需要同步修改组件视图
            if(button.component && button.component.changeView){
                button.component.changeView(button.changeProps);
            }else if(button.list){
                selectDropdownList(button, dropdown);
            }

            if(displayDropdown !== dropdown){
                setDropdownVisible(displayDropdown);
                displayDropdown = dropdown;
            }
        }else{
            if(displayDropdown === dropdown){
                displayDropdown = null;
            }
        }
    }

    /**
     * 隐藏下拉框
     * @param {*} dropdown 
     */
    var hideDropdown = function(dropdown){
        dropdown.classList.remove("active");
        if(displayDropdown === dropdown){
            displayDropdown = null;
        }
    }

    /**
     * 构建下拉列表
     * @param {*} button 
     * @param {*} dropdown 
     */
    var buildDropdownList = function(button, dropdown){
        var ul = crEle("ul");
        var list = button.list;

        button.subButtons = [];
    
        var item = null;
        var btn = null;

        for(var i = 0; i < list.length; i++){
            item = list[i];

            if(typeof(item) == "object"){
                if(item.split){
                    let li = crEle("li", "sc-toolbar-dropdown-split");
                    ul.appendChild(li);
                    continue;
                }
                btn = {...item};
                if(btn.component && btn.component.name){
                    btn.component = instantiateComponent(btn.component.name, btn.component.param);
                }
            }else{
                btn = {
                    label: item,
                    value: item
                }
            }

            let li = crEle("li");
            let spanText = crEle("span", "sc-button-text");
            let spanImg = crEle("span", "sc-button-img");

            spanText.innerText = btn.label;

            li.appendChild(spanImg);
            li.appendChild(spanText);
            ul.appendChild(li);

            btn.element = li;

            button.subButtons.push(btn);
        }

        return ul;
    }

    /**
     * 选择指定下拉选项
     * @param {*} button 
     * @param {*} dropdown 
     */
    var selectDropdownList = function(button, dropdown){
        if(button.selectedIndex == null) return;

        var lis = dropdown.querySelectorAll("li");
        var li = null;

        for(var i = 0; i < lis.length; i++){
            if(i == button.selectedIndex){
                li = lis[i];
                break;
            }
        }

        setMenuListCheck(li, dropdown);
    }

    /**
     * 设置下拉框是否可见
     * @param {*} dropdown 
     */
    var setDropdownVisible = function(dropdown, left, top){
        if(!dropdown) return false;

        if(dropdown.classList.contains("active")){
            dropdown.classList.remove("active");

            return false;
        }else{
            dropdown.classList.add("active");
            dropdown.style.left = (left ? left : 0) + "px";
            dropdown.style.top = (top ? top : 0) + "px";

            return true;
        }
    }

    /**
     * 设置菜单列表选中
     * @param {*} target 
     * @param {*} parent 
     */
    var setMenuListCheck = function(target, parent){
        if(!target || !parent) return;
        
        let checkedTarget = parent.querySelector("li.checked");
        if(checkedTarget){
            checkedTarget.classList.remove("checked");
            let img = checkedTarget.querySelector("img");
            if(img){
                img.parentNode.removeChild(img);
            }
        }
        
        target.classList.add("checked");

        let img = crEle("img");
        img.src = scToolbarResource.menuChecked;

        target.querySelector(".sc-button-img").prepend(img);
    }

    /**
     * 绑定select下拉选择事件
     * @param {*} button 
     * @param {*} listener 
     */
    var bindSelect = function(button, listener){
        if(button.bindChangeEvent) return;
        button.bindChangeEvent = true;
        button.element.addEventListener("change", (e)=>{
            let param = {};
            param[button.key] = button.elementList.find(
                item=>item.element === e.target.querySelector("option:checked")).value;
            listener(button.command, param);
        });
    }

    /**
     * 显示对话框
     * @param {*} button 
     * @param {*} listener 
     */
    var showDialog = function(button, listener){
        dialog.createView(button, listener);
    }

    /**
     * 判断check是否是选中并触发监听
     * @param {*} button 
     * @param {*} listener 
     */
    var doCheck = function(button, listener){
        var param = null;

        if(button.param){
            let regExp = /\{[\s]*checked[\s]*\}/g;
            let checkbox = button.element.querySelector("input[type='checkbox']");

            if(typeof(button.param) == "object"){
                param = cloneData(button.param);
                replaceParam(param, regExp, checkbox.checked, (val)=>{
                    return val === "true";
                });
            }else if(regExp.test(button.param)){
                param = button.param.replace(regExp, checkbox.checked);
            }
        }else{
            param = button.param;
        }

        button.listener = listener;
        listener(button.command, param, button);
    }

    /**
     * 遍历并克隆对象
     * @param {*} obj 
     * @param {*} callback 
     */
    var cloneData = function(data, callback){
        var result = Array.isArray(data) ? [] : {};
        var item = null;

        for(var i in data){
            if(callback){
                item = callback(i, data[i]);
            }else{
                item = data[i];
            }

            if(typeof(data[i]) == "object" && (data[i] != null && Object.keys(data[i]).length > 0)){
                if(item !== undefined){
                    result[i] = cloneData(item, callback);
                }
            }else{
                if(item !== undefined){
                    result[i] = item;
                }
            }
        }

        return result;
    }

    /**
     * 替换参数
     * @param {*} param 
     * @param {*} regExp 
     * @param {*} value 
     * @param {*} callback
     */
    var replaceParam = function(param, regExp, value, callback){
        for(var i in param){
            if(regExp.test(param[i])){
                param[i] = param[i].replace(regExp, value);
                if(callback){
                    param[i] = callback(param[i]);
                }
            }else if(typeof(param[i]) == "object"){
                replaceParam(param[i], regExp, value, callback);
            }
        }
    }

    /**
     * 设置归属的布局组件
     * @param {*} lay 
     */
    this.setLayout = function(lay){
        layoutRect = lay;
        dialog.setLayout(lay);
    }

    /**
     * 消息通知
     * @param {*} eventType 事件类型
     * @param {*} param
     */
    this.notify = function(eventType, param){
        if(eventType == "mousedown"){
            //隐藏下拉框
            if(displayDropdown){
                setDropdownVisible(displayDropdown);
                displayDropdown = null;
            }

            if(!param.element) return;

            let btn = null;
            let value = null;

            //控制按钮状态
            for(var i in tabButtons){
                btn = tabButtons[i];
                if(param.element[btn.prop]){
                    value = param.element[btn.prop][btn.key];
                    setButtonState(btn, btn.key, value === undefined ? null : value);
                }else if(param.paragraph && param.paragraph[btn.key] !== undefined){
                    value = param.paragraph[btn.key];
                    setButtonState(btn, btn.key, value === undefined ? null : value);
                }

                if(!btn.component || !btn.component.notify) continue;
                btn.component.notify(eventType, param);
            }

            filterMenu(param.element, param.containerType);
        }else if(eventType == "load"){
            let btn = null;

            if(param && param.setting){
                for(var i in tabButtons){
                    btn = tabButtons[i];
                    if(param.setting[btn.key] && 
                       param.setting[btn.key] == btn.value) {
                        setButtonState(btn, btn.key, btn.value);
                    }
                }
            }
        }else if(eventType == "contentChange"){
            let btn = null;

            for(var i in tabButtons){
                btn = tabButtons[i];
                if(!btn.component || !btn.component.notify) continue;
                btn.component.notify(eventType, param);
            }
        }else if(eventType == "toolbarStatusChange"){
            let btn = null;
            for(var i in tabButtons){
                btn = tabButtons[i];
                if(btn.command == param.command){
                    //有参情况，比如openDrawer
                    if(param.param){
                        let flg = false;
                        for(let i in param.param){
                            if(param.param[i] != btn.param[i]) {
                                flg = true;
                                break;
                            }
                        }
                        if(flg) continue;
                    }

                    setButtonState(btn, btn.key, param.value);
                    
                    break;
                }
            }
        }
    }

    /**
     * 设置按钮状态
     * @param {*} button 
     * @param {*} key
     * @param {*} value 
     */
    var setButtonState = function(button, key, value){
        if(button.present == "select"){
            button.effectElement.value = value;
        }else if(button.present == "button"){
            if(button.list){
                changeElementState(button, button.list.indexOf(value));
            }else if(button.value){
                changeMockButtonState(button, key, value);
            }
        }else if(button.present == "dropdown"){
            if(button.component){
                if(button.component.setProperty){
                    button.component.setProperty(key, value);
                }
            }else{
                changeDropdownState(button, key, value);
            }

            if(button.ribbon){
                let ribbonEl = button.element.querySelector(".sc-button-ribbon");
                if(ribbonEl){
                    if(value){
                        ribbonEl.style.background = value;
                    }else{
                        ribbonEl.style.background = "transparent";
                        ribbonEl.style.border = "1px solid #000";
                    }
                }
            }
        }else if(button.present == "dialog"){
        }else if(button.present == "checkbox"){
            button.effectElement.checked = value;
        }else if(button.present == "radio"){
            button.effectElement.checked = value;
        }
    }

    /**
     * 过滤菜单
     * @param {*} element 
     * @param {*} containerType
     */
    var filterMenu = function(element, containerType){
        let menu = null;
        let regular = null;

        for(let i = 0; i < menus.length; i++){
            menu = menus[i];
            if(!menu.selector) continue;

            regular = parseSelector(menu.selector);
            
            if(matchSelector(regular, element, containerType)){
                menu.headNode.style.display = "";
            }else{
                menu.headNode.style.display = "none";
                menu.headNode.classList.remove("selected");
                menu.bodyNode.classList.remove("selected");

                let m = lastMenu === menu ? prevMenu : lastMenu;
                if(m){
                    m.headNode.classList.add("selected");
                    m.bodyNode.classList.add("selected");
                }
            }
        }
    }

    /**
     * 解析选择器
     * @param {*} selector 
     */
    var parseSelector = function(selector){
        var obj = {
            type: null,
            keyVals: {},
            props:[]
        };

        var chars = "[a-z0-9_]+";
        var rule = "^(" + chars + "){0,1}[\s]*(\[[\s]*" + chars + "[\s]*[=]*[\s]*" + chars + "[\s]*\]){0,9}$";
        var regex = new RegExp(rule, "gi");

        var groups = regex.exec(selector);

        for(var i = 1; i < groups.length; i++){
            if(!groups[i]) continue;
            
            if(groups[i].indexOf("=") > -1){
                let arr = groups[i].replace(/[\[\]'']/g, "").split("=");
                obj.keyVals[arr[0]] = arr[1];
            }else if(groups[i].indexOf("[") > -1){
                obj.props.push(groups[i].replace(/[\[\]'']/g, ""));
            }else if(groups[i] != "undefined"){
                obj.type = groups[i].trim();
            }
        };

        return obj;
    }

    /**
     * 元素是否匹配选择器
     * @param {*} regular 
     * @param {*} element 
     * @param {*} containerType
     */
    var matchSelector = function(regular, element, containerType){
        let isMatch = true;

        if(regular.type != null){
            isMatch = (regular.type == element._sType || 
                regular.type == element._pType || regular.type == containerType);
        }
        
        for(let i in regular.props){
            if(element[regular.props[i]] == null){
                isMatch = false;
                break;
            }
        }

        for(let i in regular.keyVals){
            if(element[i] != regular.keyVals[i]){
                isMatch = false;
                break;
            }
        }

        return isMatch;
    }
}